package com.dongwu.manager.service.impl;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import com.dongwu.common.dao.DynamicSpecifications;
import com.dongwu.common.dao.SearchFilter;
import com.dongwu.common.service.impl.BaseServiceImpl;
import com.dongwu.manager.dao.DeviceDao;
import com.dongwu.manager.entity.Device;
import com.dongwu.manager.entity.DeviceAdsRecord;
import com.dongwu.manager.entity.OpenMarket;
import com.dongwu.manager.service.DeviceAdsRecordService;
import com.dongwu.manager.service.DeviceService;
import com.dongwu.manager.service.OpenMarketService;
import com.dongwu.security.entity.User;
import com.dongwu.security.service.IGroupService;
import com.dongwu.security.service.IUserService;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

@Service
public class DeviceServiceImpl extends BaseServiceImpl<Device, String> implements DeviceService {
	@Autowired
	private DeviceDao deviceDao;
	@Autowired
	private IGroupService iGroupService;
	@Autowired
	private IUserService userService;
	@Autowired
	private OpenMarketService openMarketService;
	@Autowired
	private DeviceAdsRecordService deviceAdsRecordService;

	Class<Device> entityClass = null;

	@SuppressWarnings("unchecked")
	public DeviceServiceImpl() {
		Type t = getClass().getGenericSuperclass();
		if (t instanceof ParameterizedType) {
			Type[] p = ((ParameterizedType) t).getActualTypeArguments();
			entityClass = (Class<Device>) p[0];
		}
	}

	@PersistenceContext
	protected EntityManager entityManager;

	@Override
	public Device findBySn(String sn) {
		List<Device> dd = deviceDao.findBySn(sn);
		for (Device device : dd) {
			if (device.getStatus() != Device.Status.referApproval) {
				return device;
			}
		}
		return null;
	}

	@Override
	public Device findById(String id) {
		return deviceDao.findById(id);
	}

	// 审核
	@Override
	public void approval(String id) {
		Device device = deviceDao.findById(id);
		device.setStatus(Device.Status.passApproval);
		deviceDao.save(device);
	}

	// 审核
	@Override
	public void referApproval(String id) {
		Device device = deviceDao.findById(id);
		device.setStatus(Device.Status.referApproval);
		deviceDao.save(device);
	}

	@Override
	public void delete(String id) {
		/* 如果当前设备已存在开启记录则清除 */
		List<OpenMarket> oms = openMarketService.findByDeviceId(id);
		if (oms != null && id != "") {
			String[] deviceIds = new String[oms.size()];
			for (int i = 0; i < oms.size(); i++) {
				deviceIds[i] = oms.get(i).getId();
			}
			openMarketService.delete(deviceIds);
		}
		super.delete(id);
	}

	@Override
	public void delete(String[] ids) {
		for (int i = 0; i < ids.length; i++) {
			/* 如果当前设备已存在开启记录则清除 */
			List<OpenMarket> oms = openMarketService.findByDeviceId(ids[i]);
			if (oms != null) {
				String[] deviceIds = new String[oms.size()];
				for (int a = 0; a < oms.size(); a++) {
					deviceIds[a] = oms.get(a).getId();
				}
				openMarketService.delete(deviceIds);
			}
		}
		super.delete(ids);
	}

	@Override
	public List<Map<String, String>> findCityCount(Map<String, Object> searchParams) {
		Map<String, SearchFilter> filters = SearchFilter.parse(searchParams);
		Specification<Device> spec = DynamicSpecifications.bySearchFilter(filters.values(), entityClass);
		// 返回当前用户的所有设备
		List<Device> devList = deviceDao.findAll(spec);
		List<Map<String, String>> result = Lists.newArrayList();
		// 存储所有的有设备的城市名
		List<String> cityList = new ArrayList<String>();
		for (int i = 0; i < devList.size(); i++) {
			if (!cityList.contains(devList.get(i).getCity())) {
				// 如果list中不包含当前city则新增
				cityList.add(devList.get(i).getCity());
			}
		}
		for (int i = 0; i < cityList.size(); i++) {
			Map<String, String> map = Maps.newHashMap();
			Integer onlineNum = 0;
			Integer offlineNum = 0;
			for (Device dev : devList) {
				if (dev.getCity().equals(cityList.get(i))) {
					if (dev.getIMStatus() == Device.iMStatusType.Offline) {
						offlineNum++;
						continue;
					}
					if (dev.getIMStatus() == Device.iMStatusType.PushOnline) {
						offlineNum++;
						continue;
					}
					if (dev.getIMStatus() == Device.iMStatusType.Online) {
						onlineNum++;
						continue;
					}
					if (dev.getStatus() == Device.Status.passApproval) {
						offlineNum++;
						continue;
					}
				}
			}
			// 写入城市名到map
			map.put("name", cityList.get(i));
			map.put("online", onlineNum.toString());
			map.put("offline", offlineNum.toString());
			result.add(map);
		}
		return result;
	}

	// 审核
	@Override
	public void check(String id, String type, String remark) {
		Device device = deviceDao.findById(id);
		if (type.equals("1")) {
			device.setStatus(Device.Status.passApproval);
			User user = userService.findByLoginName(device.getMobile());
			if (user == null) {
				user = new User();
				user.setLoginName(device.getMobile());
				user.setPassword("123456");
				user.setName(device.getBusinessName());
				user.setOutSn(device.getYunkeNum());
				user.setUserGroups(Lists.newArrayList(iGroupService.findByName("商户").getId()));
				userService.save(user);
			}

			device.setUser(user);
		} else {
			device.setStatus(Device.Status.referApproval);
			device.setRemark(remark);
		}

		deviceDao.save(device);
	}

	@Override
	public Device save(Device entity) {
		if(entity.getAppTemplate() != null){
			if(entity.getAppTemplate().getTemplateType() != null){
                if("005".equals(entity.getAppTemplate().getTemplateType().getTemplateTypeSn())){
                    entity.setTemplateTypeSn("002");
                }else if("006".equals(entity.getAppTemplate().getTemplateType().getTemplateTypeSn()) || "007".equals(entity.getAppTemplate().getTemplateType().getTemplateTypeSn())
                        || "008".equals(entity.getAppTemplate().getTemplateType().getTemplateTypeSn())){
                    entity.setTemplateTypeSn("003");
                }else{
                    entity.setTemplateTypeSn("001");
                }
			}
		}
		if (entity.getStatus() == null) {
			entity.setIMStatus(Device.iMStatusType.Offline);
			entity.setStatus(Device.Status.passApproval);
			entity.setSwitchingSpeed(2);
			return super.save(entity);
		}
		return super.update(entity);

	}

	@Override
	public Device update(Device entity) {
		entityManager.clear();
		Device dev = deviceDao.findOne(entity.getId());
		if(entity.getAppTemplate() != null){
			if(entity.getAppTemplate().getTemplateType() != null){
                if("005".equals(entity.getAppTemplate().getTemplateType().getTemplateTypeSn())){
                    entity.setTemplateTypeSn("002");
                }else if("006".equals(entity.getAppTemplate().getTemplateType().getTemplateTypeSn()) || "007".equals(entity.getAppTemplate().getTemplateType().getTemplateTypeSn())
                        || "008".equals(entity.getAppTemplate().getTemplateType().getTemplateTypeSn())){
                    entity.setTemplateTypeSn("003");
                }else{
                    entity.setTemplateTypeSn("001");
                }
			}
			if(dev.getAppTemplate() != null){
				if(!dev.getAppTemplate().getId().equals(entity.getAppTemplate().getId())){
					List<DeviceAdsRecord> dar = deviceAdsRecordService.findByDeviceId(entity.getId(), 0);
					for (DeviceAdsRecord deviceAdsRecord : dar) {
						deviceAdsRecord.setStatus(1);
					}
					deviceAdsRecordService.batchUpdate(dar);
				}
			}
		}
		return super.update(entity);
	}

	@Override
	public Long getCount(Map<String, Object> searchParams, String userId) {
		Long devList = null;
		if (userId == null) {
			// TODO Auto-generated method stub
			Map<String, SearchFilter> filters = SearchFilter.parse(searchParams);
			Specification<Device> spec = DynamicSpecifications.bySearchFilter(filters.values(), entityClass);
			// 返回当前用户的所有投放记录
			devList = deviceDao.count(spec);
		} else {
			devList = deviceDao.countByUserid(userId);
		}
		return devList;
	}
}
